#pragma once

#include "sock.hpp"
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include "Protocol.hpp"

namespace CalcServer
{
    using func_t = std::function<void(my_protocol::Request &, my_protocol::Response *)>;

    class TcpServer; // 前置声明

    // 线程所需要的信息类
    class ThreadDate
    {
        const static uint16_t default_port = 8888;

    public:
        ThreadDate(int sock, std::string ip, uint16_t port, TcpServer *ptsvr)
            : _sock(sock), _ip(ip), _port(port), _ptsvr(ptsvr)
        {
        }
        ~ThreadDate()
        {
        }
        int _sock;
        std::string _ip;
        uint16_t _port;
        TcpServer *_ptsvr; // 回调指针
    };

    class TcpServer
    {
        const static uint16_t default_port = 8888;

    public:
        TcpServer(func_t f, const uint16_t port = default_port)
            : _port(port), _func(f)
        {
        }

        // 初始化服务器
        void Init()
        {
            _listen_sock.Socket();
            _listen_sock.Bind(_port);
            _listen_sock.Listen();
        }

        // 启动服务器
        void Start()
        {
            while (true)
            {
                std::string ip;
                uint16_t port;

                int sock = _listen_sock.Accept(&ip, &port);
                if (sock == -1)
                {
                    continue;
                }

                // 创建子进程，执行业务处理
                pthread_t tid;
                ThreadDate *td = new ThreadDate(sock, ip, port, this);
                pthread_create(&tid, nullptr, threadRoutine, td);
            }
        }
        ~TcpServer()
        {
            _listen_sock.Close();
        }

    private:
        Sock _listen_sock; // 监听套接字
        uint16_t _port;    // 服务器端口号
        func_t _func;      // 上层传入的业务处理函数

        // 进行IO服务的函数
        void ServiceIO(const int &sock, const std::string ip, const uint16_t port)
        {
            std::string inBuff;
            while (true)
            {
                // 1. 读取数据
                std::string package; // 假设这是已经读取到的数据包，格式为"5\r\n1+1"
                int len = my_protocol::ReadPackage(sock, inBuff, &package);
                if (len < 0)
                    break;
                else if (len == 0)
                    continue;

                // 2. 移除报头
                my_protocol::RemoveHeader(package, len);

                // 3. 反序列化
                my_protocol::Request req;
                if (req.Deserialization(package) == false)
                {
                    logMessage(Warning, "Deserialization fail!");
                    continue;
                }

                // 4. 业务处理
                my_protocol::Response resp; // 业务处理完成后得到的响应对象
                _func(req, &resp);

                // 5. 序列化
                std::string sendMsg;
                resp.Serialization(&sendMsg);
                cout << sendMsg << endl;

                // 6. 添加报头
                my_protocol::AddHeader(sendMsg);

                // 7. 发送数据
                send(sock, sendMsg.c_str(), sendMsg.size(), 0);
            }
        }

        // 线程的执行函数
        static void *threadRoutine(void *args)
        {
            // 线程剥离
            pthread_detach(pthread_self());

            ThreadDate *td = static_cast<ThreadDate *>(args);
            string get1;
            string get2;
            // int n = send(td->_sock, sendMsg.c_str(), sendMsg.size(), 0);
            //int len = my_protocol::ReadPackage(td->_sock, get1, &get2);

            //std::cout << get1 << "-----"  << get2 << std::endl;

            td->_ptsvr->ServiceIO(td->_sock, td->_ip, td->_port);
            delete td;
            return nullptr;
        }
    };

}

